package org.cornland.systemWarning.schedule;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.cornland.systemWarning.model.DataExceptionAlarm;
import org.cornland.systemWarning.model.DataExceptionAlarmConfig;
import org.cornland.systemWarning.model.Djdwxx;
import org.cornland.systemWarning.model.Well;
import org.cornland.systemWarning.model.impl.WellTags;
import org.cornland.systemWarning.service.*;
import org.cornland.systemWarning.utils.AppUrl;
import org.cornland.systemWarning.utils.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Component
public class PiDBSchedule {

    @Autowired
    AppUrl appUrl;

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    RealdataTagService realdataTagService;

    @Autowired
    WellService wellService;

    @Autowired
    DataExceptionAlarmService dataExceptionAlarmService;

    @Autowired
    DjdwxxService djdwxxService;

    @Autowired
    private DataExceptionAlarmConfigService dataExceptionAlarmConfigService;
    @Scheduled(cron = "0 0/10 * * * ?")
    public void piDBSchedule(){
        try {
            log.info("Pi数据库异常检查开始");
            piDBWarning();
            log.info("Pi数据库异常检查结束");
        } catch (RestClientException e){
            log.error("请求接口超时,请检查");
            log.error(e.getMessage(), e);
        } catch (Exception e) {
            log.error("Pi数据库异常检查遇到问题");
            log.error(e.getMessage(), e);
        }
    }

    public void piDBWarning(){
        // 选取所有井
        List<Well> wells = wellService.selectAll();
        for (int i = 0; i < wells.size() ; i++) {
            // 每口井的数据
            Well well = wells.get(i);
            String jmjh = well.getJmjh();
            String id = well.getId();
            // 缓存取井的所有点位信息
            WellTags wellTags = realdataTagService.wellTags(id);
            // 取得所有点位信息 并且转换为List
            String tags = wellTags.getTags();
            String[] split = tags.split(",");
            List<String> tagList = Arrays.asList(split);

            if(!StringUtil.isNullOrEmpty(tags)){
//                String url = appUrl.queryRealTimeDataUrl + "?tags=" + tags;
//                URI uri = URI.create(url);
//                String tagString = restTemplate.getForObject(uri, String.class);
//
//                // 调用实时数据接口 返回jsonArray
//                JSONArray jsonArray = JSONArray.parseArray(tagString);

                // 上一次缓存的
//                JSONArray preJsonArray = realdataTagService.getTagsRequestWithCache(tags);
                // 当前新的并且更新缓存
                JSONArray foreJsonArray = realdataTagService.updateTagsRequestWithCache(tags);


                // 判断tags request后是否存在于pi
                nullPoint(foreJsonArray,tagList,id,jmjh);

                // 判断时间5分钟内有变化过没
//                timeConflict(preJsonArray,foreJsonArray,id,jmjh);

                // 查看数值类型是否为空或者0
                chechIsNullOrZero(foreJsonArray,id,jmjh);
            }
        }
    }

    public void chechIsNullOrZero(JSONArray foreJsonArray, String id, String jmjh){
        for (int i = 0; i < foreJsonArray.size() ; i++) {
            Map<String, Object> object = foreJsonArray.getObject(i, Map.class);
            String tag = (String) object.get("tag");

            // 正常String 目前皆认为是状态的json
            if(object.get("value") instanceof String){
                // String不管 状态类型与数值无关
            }
            // 目前 BigDecimal 皆可认为是油套压类的数值
            else if(object.get("value") instanceof BigDecimal){
                BigDecimal value = (BigDecimal) object.get("value");
                if(value.compareTo(BigDecimal.ZERO) == 0){
                    String message = "PI数据库点位值为0 点位为: " + tag;
                    log.warn(message);

                    QueryWrapper wrapper = new QueryWrapper();
                    wrapper.eq("tag",tag);
                    wrapper.eq("well_id",id);
                    Djdwxx djdwxx = djdwxxService.getOne(wrapper);
                    if(djdwxx!=null){
                        Integer px = djdwxx.getPx();
                        if (px == 1){
                            // 当px==1时，为瞬量点位，瞬量的值为0属于正常，不用加入系统异常信息中
                            continue;
                        }
                        String dwms = djdwxx.getDwms();
                        message = message + " 点位描述: "+dwms;
                    }

                    DataExceptionAlarm lastWithTag = dataExceptionAlarmService.getLastWithTag(id, 3, tag, 2);

                    // 不存在上一条 直接存
                    if(lastWithTag == null){
                        savePiDataException(id,message,tag,2);
                    }
                    else{
                        Integer flag = lastWithTag.getFlag();
                        // 如果上一条信息未处理则不做任何动作
                        // 如果上条已处理则添加
                        if(flag == 1){
                            savePiDataException(id,message,tag,2);
                        }
                    }

                }
            }
            else{
                if(object.get("value") ==null){
                    String message = "PI数据库点位值为null 点位为: " + tag;

                    QueryWrapper wrapper = new QueryWrapper();
                    wrapper.eq("tag",tag);
                    wrapper.eq("well_id",id);
                    Djdwxx djdwxx = djdwxxService.getOne(wrapper);
                    if(djdwxx!=null){
                        String dwms = djdwxx.getDwms();
                        message = message + " 点位描述: "+dwms;
                    }

                    log.warn(message);
                    DataExceptionAlarm lastWithTag = dataExceptionAlarmService.getLastWithTag(id, 3, tag, 3);

                    // 不存在上一条 直接存
                    if(lastWithTag == null){
                        savePiDataException(id,message,tag,3);
                    }
                    else{
                        Integer flag = lastWithTag.getFlag();
                        // 如果上一条信息未处理则不做任何动作
                        // 如果上条已处理则添加
                        if(flag == 1){
                            savePiDataException(id,message,tag,3);
                        }
                    }
                }
            }


        }

    }

    public void timeConflict(JSONArray preJsonArray, JSONArray foreJsonArray, String id, String jmjh){

        // 记录5分前的状态放入Map里
        // tag -> value
        Map<String,Object> preMap = new HashMap<>();

        for (int j = 0; j < preJsonArray.size() ; j++) {
            Map<String,Object> object = preJsonArray.getObject(j, Map.class);
            String tag = (String) object.get("tag");
            Object value = object.get("value");
            String outTime = (String) object.get("time");
            preMap.put(tag,value);

        }



        for (int i = 0; i < foreJsonArray.size() ; i++) {
            Map<String,Object> object = foreJsonArray.getObject(i, Map.class);
//            System.out.println("object " + object);
            String tag = (String) object.get("tag");

            // 外时间有可能用
            String outTime = (String) object.get("time");
//            System.out.println(outTime);

            // 如果上一轮的没发现 则是有问题的 丢失或者异常
            if(!preMap.containsKey(tag)){
                log.error(jmjh + " 点位遗失 点位为: " +tag);
                continue;
            }


            // 正常String 目前皆认为是状态的json
            if(object.get("value") instanceof String){
                String value = (String) object.get("value");
//                System.out.println(value);
            }
            // 目前 BigDecimal 皆可认为是油套压类的数值
            else if(object.get("value") instanceof BigDecimal){
                BigDecimal value = (BigDecimal) object.get("value");
//                System.out.println(value);
            }
            else{
                if(object.get("value") !=null){
                    log.error("发现不能处理的类型 value为:" + object.get("value").getClass().toString());
                }
            }




        }

    }


    /**
     * 判断查询Pi不存在
     * @param jsonArray 请求tags返回的jsonArray
     * @param tagList 数据库查出来的tag
     * @param id 井id
     * @param jmjh 井名
     */
    public void nullPoint(JSONArray jsonArray,List<String> tagList,String id,String jmjh){
        // 存储请求JSONArray里的tag
        List<String> requestTagList = new ArrayList<>();
        for (int j = 0; j <jsonArray.size() ; j++) {
            Map<String,Object> map = jsonArray.getObject(j, Map.class);
            String tag = (String) map.get("tag");
            requestTagList.add(tag);
        }

        // 如果请求的所有点位信息没找到则点位有问题
        for (int k = 0; k <tagList.size() ; k++) {
            String tag = tagList.get(k);
            if(!requestTagList.contains(tag)){
                String message = "PI数据库点位信息查询为空 点位为: " + tag;
                QueryWrapper wrapper = new QueryWrapper();
                wrapper.eq("tag",tag);
                wrapper.eq("well_id",id);
                Djdwxx djdwxx = djdwxxService.getOne(wrapper);
                if(djdwxx!=null){
                    String dwms = djdwxx.getDwms();
                    message = message + " 点位描述: "+dwms;
                }
                log.warn(message);



                DataExceptionAlarm lastWithTag = dataExceptionAlarmService.getLastWithTag(id, 3, tag, 1);

                // 不存在上一条 直接存
                if(lastWithTag == null){
                    savePiDataException(id,message,tag,1);
                }
                else{
                    Integer flag = lastWithTag.getFlag();
                    // 如果上一条信息未处理则不做任何动作
                    // 如果上条已处理则添加
                    if(flag == 1){
                        savePiDataException(id,message,tag,1);
                    }
                }

//                DataExceptionAlarm dataExceptionAlarm = new DataExceptionAlarm();
//                dataExceptionAlarm.setTag(tag);
//                dataExceptionAlarm.setPiType(1);
//                dataExceptionAlarm.setWellId(id);
//                dataExceptionAlarm.setTime(DateUtil.getCurrentTimeFormat());
//                dataExceptionAlarm.setFlag(0);
//                dataExceptionAlarm.setType(3);
//                dataExceptionAlarm.setDescription(message);
//                dataExceptionAlarmService.save(dataExceptionAlarm);

            }

        }
    }

    public void savePiDataException(String wellId, String message,String tag,Integer piType){
        //获取当前时间
        String nowTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        DataExceptionAlarmConfig dataExceptionAlarmConfig = dataExceptionAlarmConfigService.getOne(new QueryWrapper<DataExceptionAlarmConfig>().eq("type", 3));
        boolean b=false;
        if(StringUtils.isNotBlank(dataExceptionAlarmConfig.getBeganIgnore())){
            b = DateUtil.compareTime(dataExceptionAlarmConfig.getBeganIgnore(), dataExceptionAlarmConfig.getEndIgnore(), nowTime);
        }
        if(!b) {
            DataExceptionAlarm dataExceptionAlarm = new DataExceptionAlarm();
            dataExceptionAlarm.setTag(tag);
            dataExceptionAlarm.setPiType(piType);
            dataExceptionAlarm.setWellId(wellId);
            dataExceptionAlarm.setTime(DateUtil.getCurrentTimeFormat());
            dataExceptionAlarm.setFlag(0);
            dataExceptionAlarm.setType(3);
            dataExceptionAlarm.setDescription(message);
            dataExceptionAlarmService.save(dataExceptionAlarm);
        }
    }

}
